package com.sayice.robotconflict.view.page

import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.itemsIndexed
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AddCircle
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.google.gson.reflect.TypeToken
import com.sayice.robotconflict.model.Message
import com.sayice.robotconflict.model.logic.*
import com.sayice.robotconflict.model.receive.RobotEntity
import com.sayice.robotconflict.model.send.RobotUpdateInfo
import com.sayice.robotconflict.ui.screen.cdp
import com.sayice.robotconflict.ui.screen.csp
import com.sayice.robotconflict.util.GSON
import com.sayice.robotconflict.util.PRETTY_GSON
import com.sayice.robotconflict.util.vibrate
import com.sayice.robotconflict.view.control.ConfirmAndCancelButton
import com.sayice.robotconflict.view.control.CustomButton
import com.sayice.robotconflict.view.control.StrSelectDialog
import com.sayice.robotconflict.view.control.TextDialog
import com.sayice.robotconflict.view.route.Route
import com.sayice.robotconflict.viewmodel.GameViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/**
 * 个人中心页面
 */
@Composable
fun PlayerCenter(viewModel: GameViewModel) {
    val scope = rememberCoroutineScope()
    val playerInfoState by viewModel.playerInfoFlow.collectAsState()
    var selectedRobot by remember { mutableStateOf<RobotEntity?>(null) }
    var selectedIndex by remember { mutableStateOf(-1) }
    LaunchedEffect(Unit) {
        // 获取玩家信息
        viewModel.sendToServer(Message(type = "player", action = "info"))
    }
    Box(modifier = Modifier.fillMaxSize()) {
        Button(modifier = Modifier.align(Alignment.TopStart), onClick = {
            viewModel.goToPage(Route.HALL)
        }) {
            Text("返回大厅")
        }
        if (playerInfoState != null) {
            Row(modifier = Modifier.fillMaxSize()) {
                // 玩家信息
                Column(
                    modifier = Modifier
                        .weight(1.0f)
                        .fillMaxHeight(),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(playerInfoState!!.name)
                    Text("游戏场数: ${playerInfoState!!.gameNum}")
                    Text("胜率: ${playerInfoState!!.winRate}%")
                }
                Column(
                    modifier = Modifier
                        .weight(3.0f)
                        .fillMaxHeight(), verticalArrangement = Arrangement.SpaceAround
                ) {
                    // 携带的机器人
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(180.cdp)
                            .border(2.cdp, Color.Blue)
                            .padding(horizontal = 20.cdp),
                        horizontalArrangement = Arrangement.spacedBy(20.cdp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        if (playerInfoState!!.robots != null) {
                            for ((index, robot) in playerInfoState!!.robots!!.withIndex()) {
                                if (robot.carry) {
                                    Robot(robot, index, onClick = {
                                        selectedRobot = robot
                                        selectedIndex = index
                                    }, viewModel)
                                }
                            }
                        }
                    }
                    // 未携带的机器人
                    Column {
                        Row(
                            modifier = Modifier.fillMaxWidth(),
                            horizontalArrangement = Arrangement.SpaceBetween,
                            verticalAlignment = Alignment.Bottom
                        ) {
                            Text("仓库")
                            Button(onClick = {
                                selectedRobot = RobotEntity()
                                selectedIndex = -1
                            }) {
                                Text("添加")
                            }
                        }
                        LazyVerticalGrid(
                            columns = GridCells.Adaptive(140.cdp),
                            modifier = Modifier
                                .fillMaxSize()
                                .border(2.cdp, Color.Blue),
                            contentPadding = PaddingValues(20.cdp),
                            verticalArrangement = Arrangement.spacedBy(10.cdp)
                        ) {
                            if (playerInfoState!!.robots != null) {
                                itemsIndexed(playerInfoState!!.robots!!) { index, robot ->
                                    if (!robot.carry) {
                                        Robot(robot, index, onClick = {
                                            selectedRobot = robot
                                            selectedIndex = index
                                        }, viewModel)
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // 机器人编辑框
            if (selectedRobot != null) {
                RobotEditDialog(
                    robot = selectedRobot!!,
                    logics = selectedRobot!!.logics,
                    onDismissRequest = { selectedRobot = null },
                    onSave = {
                        scope.launch(Dispatchers.IO) {
                            viewModel.sendToServer(
                                Message(
                                    type = "player",
                                    action = if (selectedIndex == -1) "addRobot" else "updateRobot",
                                    data = RobotUpdateInfo(selectedIndex, it)
                                )
                            )
                            selectedRobot = null
                        }
                    },
                    onCancel = { selectedRobot = null },
                    viewModel = viewModel
                )
            }
        }
    }
}

/**
 * 机器人
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Robot(robot: RobotEntity, index: Int, onClick: () -> Unit, viewModel: GameViewModel) {
    val scope = rememberCoroutineScope()
    var expanded by remember { mutableStateOf(false) }
    val context = LocalContext.current
    Column {
        Image(
            painter = ColorPainter(Color.Blue),
            contentDescription = robot.name,
            modifier = Modifier
                .size(100.cdp)
                .combinedClickable(onClick = onClick, onLongClick = {
                    context.vibrate(longArrayOf(0, 40, 0, 0))
                    expanded = true
                })
        )
        Text(
            text = robot.name,
            modifier = Modifier.size(100.cdp, 40.cdp),
            fontSize = 30.csp,
            textAlign = TextAlign.Center,
            overflow = TextOverflow.Ellipsis
        )
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }) {
            DropdownMenuItem(onClick = {
                scope.launch(Dispatchers.IO) {
                    viewModel.sendToServer(
                        Message(
                            type = "player",
                            action = "deleteRobot",
                            data = index
                        )
                    )
                    expanded = false
                }
            }) {
                Text("删除")
            }
        }
    }
}

/**
 * 机器人编辑框
 *
 * @param robot 机器人
 * @param logics 机器人的逻辑
 * @param onDismissRequest 对话框关闭回调
 * @param onSave 保存按钮点击回调
 * @param onCancel 取消按钮点击回调
 * @param viewModel ViewModel
 */
@Composable
fun RobotEditDialog(
    robot: RobotEntity,
    logics: List<Logic>,
    onDismissRequest: () -> Unit,
    onSave: (RobotEntity) -> Unit,
    onCancel: () -> Unit,
    viewModel: GameViewModel
) {
    var editedRobot by remember { mutableStateOf(robot) }
    val editedLogics = logics.toMutableStateList()
    var openJsonDialog by remember { mutableStateOf(false) }
    Dialog(
        onDismissRequest = onDismissRequest,
        properties = DialogProperties(dismissOnClickOutside = false)
    ) {
        Column(
            modifier = Modifier
                .size(width = 1800.cdp, height = 1000.cdp)
                .background(Color.White)
                .padding(10.cdp)
        ) {
            Row(
                modifier = Modifier.weight(1.8f),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text("机器人名:")
                TextField(
                    value = editedRobot.name,
                    onValueChange = { editedRobot = editedRobot.copy(name = it) },
                    modifier = Modifier.padding(horizontal = 10.cdp)
                )
            }
            Row(
                modifier = Modifier.weight(1.0f),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text("是否携带:")
                Switch(
                    checked = editedRobot.carry,
                    onCheckedChange = { editedRobot = editedRobot.copy(carry = it) }
                )
            }
            Row(modifier = Modifier.weight(7.0f)) {
                Text("逻辑: ")
                Column {
                    var openConditionEditDialog by remember { mutableStateOf(false) }
                    var selectedTask by remember { mutableStateOf<FuncValue?>(null) }
                    var selectedIndex by remember { mutableStateOf(-1) }
                    Row(
                        modifier = Modifier.fillMaxWidth(),
                        horizontalArrangement = Arrangement.End,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        TextButton(onClick = {
                            openJsonDialog = true
                        }, modifier = Modifier.height(110.cdp)) {
                            Text("查看json")
                        }
                        IconButton(onClick = {
                            editedLogics.add(Logic(task = FuncValue()))
                        }, modifier = Modifier.size(70.cdp)) {
                            Icon(
                                imageVector = Icons.Filled.AddCircle,
                                contentDescription = "添加逻辑按钮",
                                tint = Color.Blue
                            )
                        }
                    }
                    LazyColumn(
                        modifier = Modifier
                            .fillMaxSize()
                            .border(2.cdp, Color.Blue),
                        contentPadding = PaddingValues(5.cdp),
                        verticalArrangement = Arrangement.spacedBy(8.cdp)
                    ) {
                        itemsIndexed(editedLogics) { index, logic ->
                            Row(modifier = Modifier.fillMaxWidth()) {
                                val context = LocalContext.current
                                Text("${index + 1}  ")
                                CustomButton(onClick = {
                                    selectedIndex = index
                                    openConditionEditDialog = true
                                }, onLongClick = {
                                    context.vibrate(longArrayOf(0, 40, 0, 0))
                                    editedLogics.removeAt(index)
                                    editedLogics.add(
                                        index,
                                        logic.copy(condition = null)
                                    )
                                }) {
                                    Text(
                                        text = "条件",
                                        modifier = Modifier.alpha(if (logic.condition == null) 0.5f else 1.0f)
                                    )
                                }
                                Spacer(modifier = Modifier.width(10.cdp))
                                CustomButton(onClick = {
                                    selectedIndex = index
                                    selectedTask = logic.task
                                }, onLongClick = {
                                    context.vibrate(longArrayOf(0, 40, 0, 0))
                                    editedLogics.removeAt(index)
                                }) {
                                    Text("任务")
                                }
                            }
                        }
                    }
                    // 条件编辑框
                    if (openConditionEditDialog) {
                        val selectedLogic = editedLogics[selectedIndex]
                        ConditionEditDialog(
                            condition = selectedLogic.condition
                                ?: Condition(body = ConditionBody()),
                            onDismissRequest = { openConditionEditDialog = false },
                            onConfirm = {
                                val logic = editedLogics[selectedIndex]
                                editedLogics.removeAt(selectedIndex)
                                editedLogics.add(
                                    selectedIndex,
                                    logic.copy(condition = it)
                                )
                                openConditionEditDialog = false
                            },
                            onCancel = { openConditionEditDialog = false },
                            viewModel = viewModel
                        )
                    }
                    // 任务编辑框
                    if (selectedTask != null) {
                        FuncValueEditDialog(
                            funcValue = selectedTask!!,
                            onDismissRequest = { selectedTask = null },
                            funcList = viewModel.loginInfo.setFuncs,
                            paramFuncList = with(viewModel.loginInfo) { simpleGetFuncs + complexGetFuncs },
                            onConfirm = {
                                val logic = editedLogics[selectedIndex]
                                editedLogics.removeAt(selectedIndex)
                                editedLogics.add(
                                    selectedIndex,
                                    logic.copy(task = it)
                                )
                                selectedTask = null
                            },
                            onCancel = { selectedTask = null }
                        )
                    }
                    // json查看框
                    if (openJsonDialog) {
                        TextDialog(
                            text = PRETTY_GSON.toJson(editedLogics),
                            onDismissRequest = { openJsonDialog = false },
                            width = 1800.cdp, height = 1000.cdp
                        )
                    }
                }
            }
            ConfirmAndCancelButton(
                modifier = Modifier.weight(1.0f),
                onConfirm = {
                    editedRobot.logics = editedLogics
                    onSave(editedRobot)
                }, onCancel = onCancel,
                confirmName = "保存"
            )
        }
    }
}

/**
 * 逻辑条件编辑框
 *
 * @param level 条件层级
 * @param condition 条件
 * @param onDismissRequest 对话框关闭回调
 * @param onConfirm 确定按钮点击回调
 * @param onCancel 取消按钮点击回调
 */
@Composable
fun ConditionEditDialog(
    level: Int = 0,
    condition: Condition,
    onDismissRequest: () -> Unit,
    onConfirm: (Condition) -> Unit,
    onCancel: () -> Unit,
    viewModel: GameViewModel
) {
    var editedCondition by remember { mutableStateOf(condition) }
    var operatorSelectList: List<String>? by remember { mutableStateOf(null) }
    var onOperatorSelect: (String) -> Unit by remember { mutableStateOf({}) }
    var openJsonDialog by remember { mutableStateOf(false) }
    Dialog(
        onDismissRequest = onDismissRequest,
        properties = DialogProperties(dismissOnClickOutside = false)
    ) {
        Column(
            modifier = Modifier
                .size(width = 1800.cdp, height = 1000.cdp)
                .background(Color.White)
                .padding(10.cdp)
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(if (level == 0) "" else "层级: $level")
                Row(verticalAlignment = Alignment.CenterVertically) {
                    TextButton(onClick = {
                        openJsonDialog = true
                    }, modifier = Modifier.height(110.cdp)) {
                        Text("查看json")
                    }
                    Text("组合条件:")
                    Switch(checked = editedCondition.body == null,
                        onCheckedChange = {
                            editedCondition = editedCondition.copy(
                                body = if (editedCondition.body == null) ConditionBody() else null
                            )
                        })
                }
            }
            if (editedCondition.body == null) {
                var selectedSubCond by remember { mutableStateOf<Condition?>(null) }
                if (editedCondition.subConds == null) {
                    editedCondition.subConds = SubConds()
                }
                Column {
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Text("条件1: ")
                        Button(onClick = {
                            selectedSubCond = editedCondition.subConds!!.subCond1
                        }) {
                            Text("条件1")
                        }
                    }
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Text("操作符: ")
                        Button(onClick = {
                            operatorSelectList = viewModel.loginInfo.logicOperators
                            onOperatorSelect = {
                                editedCondition.subConds!!.operator = it
                                editedCondition = editedCondition.copy()
                            }
                        }) {
                            Text(editedCondition.subConds!!.operator)
                        }
                    }
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Text("条件2: ")
                        Button(onClick = {
                            selectedSubCond = editedCondition.subConds!!.subCond2
                        }) {
                            Text("条件2")
                        }
                    }
                }
                // 子条件编辑框
                if (selectedSubCond != null) {
                    ConditionEditDialog(
                        level = level + 1,
                        condition = selectedSubCond!!,
                        onDismissRequest = { selectedSubCond = null },
                        onConfirm = {
                            if (it.body != null || it.subConds != null) {
                                selectedSubCond!!.body = it.body
                                selectedSubCond!!.subConds = it.subConds
                                editedCondition = editedCondition.copy()
                            }
                            selectedSubCond = null
                        },
                        onCancel = { selectedSubCond = null }, viewModel = viewModel
                    )
                }
            } else {
                var selectedOperand by remember { mutableStateOf<FuncValue?>(null) }
                editedCondition.subConds = null
                Column {
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Text("操作数1: ")
                        Button(onClick = { selectedOperand = editedCondition.body!!.operand1 }) {
                            Text(editedCondition.body!!.operand1.func)
                        }
                    }
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Text("操作符:  ")
                        Button(onClick = {
                            operatorSelectList = viewModel.loginInfo.compareOperators
                            onOperatorSelect = {
                                editedCondition.body!!.operator = it
                                editedCondition = editedCondition.copy()
                            }
                        }) {
                            Text(editedCondition.body!!.operator)
                        }
                    }
                    Row(verticalAlignment = Alignment.CenterVertically) {
                        Text("操作数2: ")
                        Button(onClick = { selectedOperand = editedCondition.body!!.operand2 }) {
                            Text(editedCondition.body!!.operand2.func)
                        }
                    }
                }
                // 操作数编辑框
                if (selectedOperand != null) {
                    FuncValueEditDialog(
                        funcValue = selectedOperand!!,
                        onDismissRequest = { selectedOperand = null },
                        funcList = viewModel.loginInfo.simpleGetFuncs,
                        paramFuncList = with(viewModel.loginInfo) { simpleGetFuncs + complexGetFuncs },
                        onConfirm = {
                            selectedOperand!!.func = it.func
                            selectedOperand!!.params = it.params
                            editedCondition = editedCondition.copy()
                            selectedOperand = null
                        },
                        onCancel = { selectedOperand = null }
                    )
                }
            }
            ConfirmAndCancelButton(onConfirm = { onConfirm(editedCondition) }, onCancel = onCancel)
        }
        // 操作符选择框
        if (operatorSelectList != null) {
            StrSelectDialog(strList = operatorSelectList!!, width = 1300.cdp, height = 800.cdp,
                onDismissRequest = { operatorSelectList = null }) {
                onOperatorSelect(it)
                operatorSelectList = null
            }
        }
        // json查看框
        if (openJsonDialog) {
            TextDialog(
                text = PRETTY_GSON.toJson(editedCondition),
                onDismissRequest = { openJsonDialog = false },
                width = 1800.cdp, height = 1000.cdp
            )
        }
    }
}

/**
 * 函数值编辑框，用于编辑操作数 (Operand) 或者任务 (Task)
 *
 * @param funcValue 函数值 (操作数或任务)
 * @param onDismissRequest 对话框关闭回调
 * @param funcList 可选择的函数列表
 * @param paramFuncList 可选择的参数函数列表
 * @param onConfirm 确定按钮点击回调
 * @param onCancel 取消按钮点击回调
 */
@Composable
fun FuncValueEditDialog(
    funcValue: FuncValue,
    onDismissRequest: () -> Unit,
    funcList: List<String>,
    paramFuncList: List<String>,
    onConfirm: (FuncValue) -> Unit,
    onCancel: () -> Unit
) {
    var editedFuncValue by remember { mutableStateOf(funcValue) }
    var params by rememberSaveable { mutableStateOf(editedFuncValue.params?.toString() ?: "") }
    var funcSelectList: List<String>? by remember { mutableStateOf(null) }
    var onFuncSelect: (String) -> Unit by remember { mutableStateOf({}) }
    Dialog(
        onDismissRequest = onDismissRequest,
        properties = DialogProperties(dismissOnClickOutside = false)
    ) {
        Column(
            modifier = Modifier
                .size(width = 1800.cdp, height = 1000.cdp)
                .background(Color.White)
                .padding(10.cdp)
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(20.cdp),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text("函数: ")
                Button(onClick = {
                    funcSelectList = funcList
                    onFuncSelect = { editedFuncValue = editedFuncValue.copy(func = it) }
                }) {
                    Text(editedFuncValue.func)
                }
            }
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(text = "参数:", modifier = Modifier.weight(0.6f))
                TextField(
                    value = params,
                    onValueChange = { params = it },
                    modifier = Modifier.weight(3.0f),
                    maxLines = 5
                )
                Button(onClick = {
                    funcSelectList = paramFuncList
                    onFuncSelect = { params = "[{\"func\": \"$it\"}]" }
                }, modifier = Modifier.weight(1.0f)) {
                    Text("函数")
                }
            }
            ConfirmAndCancelButton(onConfirm = {
                try {
                    if (editedFuncValue.func.isNotEmpty()) {
                        editedFuncValue.params = GSON.fromJson<List<Any?>>(
                            params,
                            object : TypeToken<List<Any?>>() {}.type
                        )
                    }
                } catch (_: Exception) {
                }
                onConfirm(editedFuncValue)
            }, onCancel = onCancel)
        }
        // 函数选择框
        if (funcSelectList != null) {
            StrSelectDialog(strList = funcSelectList!!, width = 1300.cdp, height = 800.cdp,
                onDismissRequest = { funcSelectList = null }) {
                onFuncSelect(it)
                funcSelectList = null
            }
        }
    }
}